-- to import My in ~/.ghc/, use `ghci -i$HOME/.ghc/`
module My
( rw, interactLn
, se, sl
, primes
, baseDigits, showIntegralAtBase, withBaseShowIntegral
, showHex,showOct,showBin
, readHex,readOct
, (.>), (|$), mapReduce, andF, orF
, groupIf, groupEq, groupAnd, (|-|)
) where
import Data.Char(intToDigit)
import qualified Data.List as L
import Data.Foldable(traverse_)
import qualified Numeric as N

rw ifn ofn fun = readFile ifn >>= writeFile ofn . fun
interactLn fun = interact $ (++"\n") . fun

--show each
se :: (Show a, Foldable t) => t a -> IO () -- haskell need this
se = traverse_ (putStrLn . show)
--show list (with list index)
sl :: Show a => [a] -> IO () -- haskell need this
sl = se . zip [0..]

primes = fp [2..] where fp (p:ns) = p : fp [x | x<-ns, x `mod` p /=0]

-- read and show hex, oct, bin, etc.
baseDigits = ['0'..'9']++['a'..'z']
showIntegralAtBase i b = N.showIntAtBase b (baseDigits!!) i ""
withBaseShowIntegral = flip showIntegralAtBase
showHex i = N.showHex i ""
showOct i = N.showOct i ""
showBin i = N.showIntAtBase 2 intToDigit i ""
readHex = fst . head . N.readHex
readOct = fst . head . N.readOct

-- hof
infixl 9 .>
f .> g = g . f
infixl 9 |$
fs |$ x = fmap ($x) fs
mapReduce fs r = r . (fs|$)
andF fs = mapReduce fs and
orF fs = mapReduce fs or

-- list
groupIf = L.groupBy
groupEq f = groupIf $ \x y->f x==f y
groupAnd f = groupIf $ \x y->f x&&f y
a |-| b = filter (`L.notElem` b) a
